#include "Renderer2D.h"
#include "VertexArray.h"
#include "Shader.h"
#include "RenderCommand.h"
#include "Debug/Instrumentor.h"

namespace Hazel {
    struct Renderer2DStorage{
        Ref<VertexArray> QuadVertexArray;
        Ref<Shader> TextureShader;
        // 增加WhiteTexture纹理，用于手动生成一个白色的纹理
        Ref<Texture2D> WhiteTexture;
    };

    static Renderer2DStorage* s_Data;

    void Renderer2D::Init() {
        HZ_PROFILE_FUNCTION();
        s_Data = new Renderer2DStorage();
        s_Data->QuadVertexArray = Hazel::VertexArray::Create();
        float squareVertices[5 * 4] = {
                -0.5, -0.5f, 0.0f, 0.0f, 0.0f,
                0.5, -0.5f, 0.0f, 1.0f, 0.0f,
                0.5, 0.5f, 0.0f, 1.0f, 1.0f,
                -0.5, 0.5f, 0.0f, 0.0f, 1.0f
        };

        Ref<VertexBuffer> squareVB = VertexBuffer::Create(squareVertices, sizeof(squareVertices));
        squareVB->SetLayout({
                                    {Hazel::ShaderDataType::Float3, "a_Position"},
                                    {Hazel::ShaderDataType::Float2, "a_TexCoord"}
                            });
        s_Data->QuadVertexArray->AddVertexBuffer(squareVB);

        uint32_t squareIndices[6] = {0, 1, 2, 2,3, 0};
        Ref<IndexBuffer> squareIB = IndexBuffer::Create(squareIndices, sizeof(squareIndices) / sizeof(uint32_t));
        s_Data->QuadVertexArray->SetIndexBuffer(squareIB);

        // 初始化时，顶一个一个宽高1*1的纹理
        s_Data->WhiteTexture = Texture2D::Create(1,1);
        // 纹理为纯白色，只有一个像素,一个RGBA像素是32位8*4
        uint32_t whiteTextureData = 0xffffffff;
        s_Data->WhiteTexture->SetData(&whiteTextureData, sizeof(uint32_t));

        s_Data->TextureShader = Hazel::Shader::Create("../assets/shaders/Texture.glsl");
        s_Data->TextureShader->Bind();
        s_Data->TextureShader->SetInt("u_Texture", 0);

    }

    void Renderer2D::Shutdown() {
        HZ_PROFILE_FUNCTION();
        delete s_Data;
    }

    void Renderer2D::BeginScene(const OrthographicCamera &camera) {
        HZ_PROFILE_FUNCTION();
        s_Data->TextureShader->Bind();
        s_Data->TextureShader->SetMat4("u_ViewProjection", camera.GetViewProjectionMatrix());
    }

    void Renderer2D::EndScene() {
        HZ_PROFILE_FUNCTION();
    }

    // BeginScene中更新Camera变换矩阵和正交投影变换矩阵
    void Renderer2D::DrawQuad(const glm::vec2 &position, const glm::vec2 &size, const glm::vec4 &color) {
        DrawQuad({position.x, position.y, 0.0f}, size, color);
    }

    // DrawQuad中增加矩形坐标、缩放的处理
    void Renderer2D::DrawQuad(const glm::vec3 &position, const glm::vec2 &size, const glm::vec4 &color) {
        HZ_PROFILE_FUNCTION();
        s_Data->TextureShader->SetFloat4("u_Color", color);
        s_Data->WhiteTexture->Bind();
        glm::mat4 transform = glm::translate(glm::mat4(1.0f), position) * glm::scale(glm::mat4(1.0), {size.x, size.y, 1.0f});
        s_Data->TextureShader->SetMat4("u_Transform", transform);
        s_Data->QuadVertexArray->Bind();
        RenderCommand::DrawIndexed(s_Data->QuadVertexArray);
    }

    //重写DrawQuad函数
    void Renderer2D::DrawQuad(const glm::vec2 &position, const glm::vec2 &size, const Ref<Texture2D> &texture) {
        DrawQuad({position.x, position.y, 0.f}, size, texture);
    }

    void Renderer2D::DrawQuad(const glm::vec3 &position, const glm::vec2 &size, const Ref<Texture2D> &texture) {
        HZ_PROFILE_FUNCTION();
        s_Data->TextureShader->Bind();
        s_Data->TextureShader->SetFloat4("u_Color", glm::vec4(1.0f));
        glm::mat4 transform = glm::translate(glm::mat4(1.0f), position) * glm::scale(glm::mat4(1.0), {size.x, size.y, 1.0f});
        s_Data->TextureShader->SetMat4("u_Transform", transform);
        texture->Bind();

        s_Data->QuadVertexArray->Bind();
        RenderCommand::DrawIndexed(s_Data->QuadVertexArray);
    }
}
